package com.engine.api.gdyjs.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.engine.api.gdyjs.entity.*;
import com.engine.api.gdyjs.service.AssetsService;
import com.engine.api.gdyjs.util.*;
import com.engine.api.gdyjs.web.AssetsAction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import weaver.conn.RecordSet;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.logging.Logger;
import java.util.stream.Collectors;

public class AssetsServiceImpl implements AssetsService {

    private static final int SCALE = 4;
    private static final Log logger = LogFactory.getLog(AssetsServiceImpl.class);
    private Set<String> errorSet = new HashSet<>(); // 使用Set提高重复检查效率

    // 园区配置
    private static final Map<String, String> PARK_CONFIG = new HashMap<>();
    static {
        PARK_CONFIG.put("牧马山园区", "mmsyq");
        PARK_CONFIG.put("科学城园区", "kxcyq");
        PARK_CONFIG.put("大装置园区", "dzzyq");
        PARK_CONFIG.put("文星产业园", "wxcyys");
        PARK_CONFIG.put("其他园区", "other");
    }

    @Override
    public String getAssets(String join, int qx, int userDepartment) {
        JSONObject result = new JSONObject();
        errorSet.clear(); // 每次请求清理错误集合
        if(qx==0 && !"0".equals(join)){
            result.put("error", "权限不够");
            return result.toJSONString();
        }
        long time1 = new Date().getTime();
        List<AssetsInfo> assetsInfos = loadAssetsFromDB(join, qx);
        List<ZczjStatInfo> zczjStatInfos = loadZczjStatInfoFromDB(join, qx);
        long hs1 = new Date().getTime() - time1;
        logger.info("查询列表耗时："+hs1);
        // 过滤掉已处置的数据
        List<AssetsInfo> filteredList = assetsInfos.stream()
                .filter(asset -> !"已处置".equals(asset.getZcsyzt()))
                .collect(Collectors.toList());
        List<AssetsInfo> yczList = assetsInfos.stream()
                .filter(asset -> "已处置".equals(asset.getZcsyzt()))
                .collect(Collectors.toList());
        BigDecimal totalValue = calculateTotalValue(filteredList);
        BigDecimal totalValueYscgje = calculateTotalValueYscgje(filteredList);
        List<AssetsInfo> zcdlList = filteredList.stream()
                .filter(asset -> "设备".equals(asset.getZcdl()))
                .collect(Collectors.toList());
        result.put("assetsTotalMoney", totalValue);
        result.put("assetsTotalNum", filteredList.size());
        if (filteredList.isEmpty()) {
            result.put("assets", Collections.emptyList());
            return result.toJSONString();
        }
        // 组装页面数据
        long time = new Date().getTime();
        assemblePageData(result, filteredList,zczjStatInfos,totalValue,yczList,totalValueYscgje,zcdlList);
        long hs = new Date().getTime() - time;
        logger.info("组装耗时："+hs);
        result.put("role", qx);
        result.put("departId", userDepartment);
        result.put("问题数据", new ArrayList<>(errorSet)); // 转换为List返回
        return result.toJSONString();
    }

    // 统一添加错误信息的方法
    private void addError(String errorMsg) {
        errorSet.add(errorMsg);
    }

    private List<AssetsInfo> loadAssetsFromDB(String join, int qx) {
        List<AssetsInfo> assetsInfos = new ArrayList<>();
        // 优化SQL查询，只查询必要的字段而不是所有字段
        String sql = "";
        // 定义需要查询的字段列表
        String requiredFields = "id, zcmc, zcrkbh, lb, zrbm, zrr, cfyq, sbzt, zcsyzt, zcyt, azlx, zjnxn, czlx, zcdl, zcrkbh,qyrq,czrq," +
                               "yscgjewy,  zcjzwy,  gyswb, xh,  pp, ggcs,cgfs, gys,zcytmx, sydd, zczt,rkrq,rzsj,zcdqcbwy,ljzjewy";
        if (qx == 1) {
            sql = "select " + requiredFields + " from uf_zcxxk where zrbm in (" + join + ")";
        } else {
            sql = "select " + requiredFields + " from uf_zcxxk";
        }

        RecordSet recordSet = new RecordSet();
        recordSet.executeQuery(sql);
        // 批量处理记录
        while (recordSet.next()) {
            assetsInfos.add(extractAssetsInfo(recordSet));
        }

        // 批量加载责任人信息
        loadPersonInfoBatch(assetsInfos);
        // 批量加载部门名称信息
        loadDepartmentInfoBatch(assetsInfos);

        return assetsInfos;
    }
    // 折旧统计数据查询
    private List<ZczjStatInfo> loadZczjStatInfoFromDB(String join, int qx) {
        List<ZczjStatInfo> zczjStatInfos = new ArrayList<>();
        // 优化SQL查询，只查询必要的字段而不是所有字段
        String sql = "";
        // 定义需要查询的字段列表
        String requiredFields = "zcbq,gxrq, zcjz,zrbm,cfyq";
        if (qx == 1) {
            sql = "select " + requiredFields + " from uf_zcjz_y_m where zrbm in (" + join + ")";
        } else {
            sql = "select " + requiredFields + " from uf_zcjz_y_m";
        }
        RecordSet recordSet = new RecordSet();
        recordSet.executeQuery(sql);
        // 批量处理记录
        while (recordSet.next()) {
            zczjStatInfos.add(extractZczjStatInfo(recordSet));
        }
        zczjStatInfoLoadDepartmentInfoBatch(zczjStatInfos);
        return zczjStatInfos;
    }

    // 批量加载责任人信息
    private void loadPersonInfoBatch(List<AssetsInfo> assetsInfos) {
        Set<String> personIds = new HashSet<>();
        for (AssetsInfo asset : assetsInfos) {
            String zrr = asset.getZrr();
            if (zrr != null && !zrr.isEmpty() && !zrr.matches("[\\u4e00-\\u9fa5]")) { // 如果责任人不是中文名，可能是ID
                personIds.add(zrr);
            }
        }

        if (!personIds.isEmpty()) {
            Map<String, String> personMap = new HashMap<>();
            String personSql = "select id, lastname from hrmresource where id in (" + String.join(",", personIds) + ")";
            RecordSet recordSet = new RecordSet();
            recordSet.executeQuery(personSql);
            while (recordSet.next()) {
                personMap.put(recordSet.getString("id"), recordSet.getString("lastname"));
            }

            // 更新责任人名称
            for (AssetsInfo asset : assetsInfos) {
                String zrr = asset.getZrr();
                if (zrr != null && personMap.containsKey(zrr)) {
                    asset.setZrr(personMap.get(zrr));
                    asset.setZrrId(zrr);
                }
            }
        }
    }

    // 批量加载部门信息
    private void zczjStatInfoLoadDepartmentInfoBatch(List<ZczjStatInfo> zczjStatInfos) {
        Set<String> deptIds = new HashSet<>();
        for (ZczjStatInfo zczjStatInfo : zczjStatInfos) {
            String departId = zczjStatInfo.getZrbm();
            if (departId != null && !departId.isEmpty()) {
                deptIds.add(departId);
            }
        }

        if (!deptIds.isEmpty()) {
            Map<String, String> deptMap = new HashMap<>();
            String deptSql = "select id, departmentname from hrmdepartment where id in (" + String.join(",", deptIds) + ")";
            RecordSet recordSet = new RecordSet();
            recordSet.executeQuery(deptSql);
            while (recordSet.next()) {
                deptMap.put(recordSet.getString("id"), recordSet.getString("departmentname"));
            }

            // 更新部门名称
            for (ZczjStatInfo zczjStatInfo : zczjStatInfos) {
                String departId = zczjStatInfo.getZrbm();
                if (departId != null && deptMap.containsKey(departId)) {
                    zczjStatInfo.setZrbm(deptMap.get(departId));
                }
            }
        }
    }

    private void assemblePageData(JSONObject result, List<AssetsInfo> assetsInfos, List<ZczjStatInfo> zczjStatInfos,BigDecimal totalValue,List<AssetsInfo> yczList,BigDecimal totalValueYscgje,List<AssetsInfo> assetsInfosYscgje) {
        // 预计算和缓存一些常用的统计数据，避免重复计算
        Map<String, List<AssetsInfo>> parkGroupedAssets = assetsInfos.stream()
                .filter(asset -> asset.getCfyq() != null)
                .collect(Collectors.groupingBy(AssetsInfo::getCfyq));

        Map<String, List<ZczjStatInfo>> parkGroupedZczjStatInfos = zczjStatInfos.stream()
                .filter(zczjStatInfo -> zczjStatInfo.getCfyq() != null)
                .collect(Collectors.groupingBy(ZczjStatInfo::getCfyq));

        Map<String, List<AssetsInfo>> departmentGroupedAssets = assetsInfos.stream()
                .filter(asset -> asset.getZrbm() != null)
                .collect(Collectors.groupingBy(AssetsInfo::getZrbm));

        Map<String, List<AssetsInfo>> statusGroupedAssets = assetsInfos.stream()
                .filter(asset -> asset.getSbzt() != null)
                .collect(Collectors.groupingBy(AssetsInfo::getSbzt));

        Map<String, List<ZczjStatInfo>> departGroupedZczjStatInfos = zczjStatInfos.stream()
                .filter(zczjStatInfo -> zczjStatInfo.getZrbm() != null)
                .collect(Collectors.groupingBy(ZczjStatInfo::getZrbm));

        Map<String, List<AssetsInfo>> departmentGroupedAssetsYzc = yczList.stream()
                .filter(asset -> asset.getZrbm() != null)
                .collect(Collectors.groupingBy(AssetsInfo::getZrbm));
        Map<String, List<AssetsInfo>> parkGroupedAssetsYzc = yczList.stream()
                .filter(asset -> asset.getCfyq() != null)
                .collect(Collectors.groupingBy(AssetsInfo::getCfyq));
        // 1. 园区设备总览（使用缓存的分组数据）
        result.put("yqsbzl", buildParkOverview(assetsInfos, parkGroupedAssets,parkGroupedZczjStatInfos,parkGroupedAssetsYzc));

        // 2. 设备资产状态占比（使用缓存的分组数据）
        result.put("sbzczt", buildAssetStatusStatistics(assetsInfos, statusGroupedAssets, totalValue));

        // 3. 各种维度统计 - 使用缓存的总价值，避免重复计算
        result.put("cgfs", buildDimensionStatistics(assetsInfos, AssetsInfo::getCgfs, "采购方式", totalValue));
        result.put("syzt", buildDimensionStatistics(assetsInfos, AssetsInfo::getZcsyzt, "运行状态", totalValue));
        result.put("zjnx", buildDimensionStatistics(assetsInfos, AssetsInfo::getZjnxn, "折旧年限", totalValue));
//        result.put("czlx", buildDimensionStatistics(assetsInfos, AssetsInfo::getCzlx, "处置类型", totalValue));
        result.put("lb", buildDimensionStatistics(assetsInfosYscgje, AssetsInfo::getLb, "类别", totalValue));
        result.put("cfyq", buildDimensionStatistics(assetsInfos, AssetsInfo::getCfyq, "存放园区", totalValue));
        result.put("sbzt", buildDimensionStatistics(assetsInfos, AssetsInfo::getSbzt, "设备状态", totalValue));
        result.put("zcdl", buildDimensionStatistics(assetsInfos, AssetsInfo::getZcdl, "资产大类", totalValue));
        result.put("zcyt", buildDimensionStatistics(assetsInfos, AssetsInfo::getZcyt, "资产用途", totalValue));
        // 定义统计配置
//        Map<String, StatConfig> statConfigs = new LinkedHashMap<>();
//        statConfigs.put("cgfs", new StatConfig(AssetsInfo::getCgfs, "采购方式"));
//        statConfigs.put("syzt", new StatConfig(AssetsInfo::getZcsyzt, "运行状态"));
//        statConfigs.put("zjnx", new StatConfig(AssetsInfo::getZjnxn, "折旧年限"));
////        statConfigs.put("czlx", new StatConfig(AssetsInfo::getCzlx, "处置类型"));
//        statConfigs.put("lb", new StatConfig(AssetsInfo::getLb, "类别"));
//        statConfigs.put("cfyq", new StatConfig(AssetsInfo::getCfyq, "存放园区"));
//        statConfigs.put("sbzt", new StatConfig(AssetsInfo::getSbzt, "设备状态"));
//        statConfigs.put("zcdl", new StatConfig(AssetsInfo::getZcdl, "资产大类"));
//        statConfigs.put("zcyt", new StatConfig(AssetsInfo::getZcyt, "资产用途"));

//        // 并行执行所有统计任务
//        Map<String, CompletableFuture<Object>> futures = new HashMap<>();
//        for (Map.Entry<String, StatConfig> entry : statConfigs.entrySet()) {
//            String key = entry.getKey();
//            StatConfig config = entry.getValue();
//
//            CompletableFuture<Object> future = CompletableFuture.supplyAsync(() ->
//                    buildDimensionStatistics(assetsInfos, config.getter, config.desc, totalValue)
//            );
//            futures.put(key, future);
//        }

//        // 等待所有任务完成并收集结果
//        for (Map.Entry<String, CompletableFuture<Object>> entry : futures.entrySet()) {
//            try {
//                result.put(entry.getKey(), entry.getValue().join());
//            } catch (Exception e) {
//                // 记录错误，但继续执行其他任务
//                System.err.println("统计任务 " + entry.getKey() + " 执行失败: " + e.getMessage());
//                result.put(entry.getKey(), Collections.emptyMap()); // 返回空结果
//            }
//        }
        // 处置类型单独处理
        result.put("czlx", buildDimensionStatistics(yczList, AssetsInfo::getCzlx, "处置类型", totalValueYscgje));
        // 4. 部门资产统计（使用缓存的分组数据）
        result.put("department", buildDepartmentStatistics(assetsInfos, departmentGroupedAssets, totalValue,departGroupedZczjStatInfos,departmentGroupedAssetsYzc));

        // 5. 资产折旧分析--
        result.put("zczjtj", ZjStatUtil.getCurrentPeriodFinancialReport(zczjStatInfos));

        // 6. 部门设备信息（使用缓存的分组数据）
        result.put("departmentAssetsDetailsInfoList", buildDepartmentAssetsDetails(departmentGroupedAssets));

        // 7. 园区设备信息（使用缓存的分组数据）
        result.put("yqAssetsDetailsInfos", buildParkAssetsDetails(parkGroupedAssets));
        // 8. 入库统计
        result.put("rktj",RkStatUtils.getCurrentPeriodDetailReport(assetsInfos));
        // 9. 资产价值数量统计
        result.put("zcjzsltj", AssetsMoneyNumStatUtils.getCurrentPeriodDetailReport(assetsInfos));
        // 10. 资产报废统计
        result.put("zcbftj", AssetsBfStatUtils.getCurrentPeriodDetailReport(yczList));
    }

    private JSONObject buildParkOverview(List<AssetsInfo> assetsInfos, Map<String, List<AssetsInfo>> parkGroupedAssets, Map<String, List<ZczjStatInfo>> parkGroupedZczjStatInfos,Map<String, List<AssetsInfo>> parkGroupedAssetsYzc) {
        JSONObject overview = new JSONObject();
        JSONObject list = new JSONObject();
        List<JSONObject> yqzctjList = new ArrayList<>();
        // 使用预分组的数据，避免重复分组
        PARK_CONFIG.forEach((parkName, parkKey) -> {
            List<AssetsInfo> parkAssets = parkGroupedAssets.get(parkName);
            List<ZczjStatInfo> zczjStatInfos = parkGroupedZczjStatInfos.get(parkName);
            List<AssetsInfo> yczList = parkGroupedAssetsYzc.get(parkName);
            JSONObject yqzctjxq = new JSONObject();
            yqzctjxq.put("count", parkAssets != null ? parkAssets.size() : 0);
            yqzctjxq.put("yqmc", parkName);
            String yqdz = "";
            if("牧马山园区".equals(parkName)){
                yqdz = "双流区牧马山";
            }else if("科学城园区".equals(parkName)){
                yqdz = "天府新区兴隆湖";
            }else if("大装置园区".equals(parkName)){
                yqdz = "天府新区新兴街道";
            }else if("文星产业园".equals(parkName)){
                yqdz = "双流区文星镇";
            }else{
                yqdz ="";
            }
            yqzctjxq.put("yqdz", yqdz);
            yqzctjxq.put("totalMoneyJz", parkAssets != null ? calculateTotalValue(parkAssets) : BigDecimal.ZERO);
            yqzctjList.add(yqzctjxq);
            if (parkAssets != null) {
                list.put(parkName, buildParkStatistics(parkAssets,zczjStatInfos,yczList));
            }
        });

        overview.put("list", list);
        overview.put("yqzctj", yqzctjList);
        return overview;
    }

    private JSONObject buildParkStatistics(List<AssetsInfo> parkAssets , List<ZczjStatInfo> zczjStatInfos,List<AssetsInfo> yczList) {
        JSONObject parkStats = new JSONObject();
        BigDecimal totalSumJz = calculateTotalValueJz(parkAssets);
        BigDecimal totalSumYz = calculateTotalValue(parkAssets);

        parkStats.put("count", parkAssets.size());
        parkStats.put("totalMoneyJz", totalSumJz);
        parkStats.put("totalMoneyYz", totalSumYz);
        parkStats.put("zrrzcjzpm", buildPersonAssetRanking(parkAssets, totalSumYz,"park"));
        parkStats.put("zcdl", buildCategoryStatistics(parkAssets, AssetsInfo::getZcdl, totalSumYz,"资产大类"));
        parkStats.put("zcyt", buildCategoryStatistics(parkAssets, AssetsInfo::getZcyt, totalSumYz,"资产用途"));
        parkStats.put("sbzt", buildCategoryStatistics(parkAssets, AssetsInfo::getSbzt, totalSumYz,"设备状态"));
        parkStats.put("cgfs", buildCategoryStatistics(parkAssets, AssetsInfo::getCgfs, totalSumYz,"采购方式"));
        parkStats.put("currentPeriodDetailReport", RkStatUtils.getCurrentPeriodDetailReport(parkAssets));
        parkStats.put("currentPeriodFinancialReport", ZjStatUtil.getCurrentPeriodFinancialReport(zczjStatInfos));
        // 资产价值数量统计
        parkStats.put("zcjzsltj", AssetsMoneyNumStatUtils.getCurrentPeriodDetailReport(parkAssets));
        // 资产报废统计
        parkStats.put("zcbftj", AssetsBfStatUtils.getCurrentPeriodDetailReport(yczList));
        return parkStats;
    }

    private List<ZrrAssetStat> buildPersonAssetRanking(List<AssetsInfo> assets, BigDecimal totalSum,String type) {
        Map<String, List<AssetsInfo>> groupedByPerson = new HashMap<>();
        if("park".equals(type)) {
            groupedByPerson = assets.stream()
                    .filter(asset -> asset.getZrbm() != null)  // 过滤掉 zrbm 为 null 的数据
                    .collect(Collectors.groupingBy(AssetsInfo::getZrbm));
            return groupedByPerson.entrySet().stream()
                    .map(entry -> createDepartAssetStat(entry.getKey(), entry.getValue(), totalSum))
                    .sorted(Comparator.comparing(ZrrAssetStat::getRatio, Comparator.reverseOrder()))
                    .collect(Collectors.toList());
        }else {
             groupedByPerson = assets.stream()
                    .filter(asset -> asset.getZrr() != null)  // 过滤掉 zrr 为 null 的数据
                    .collect(Collectors.groupingBy(AssetsInfo::getZrr));
            return groupedByPerson.entrySet().stream()
                    .map(entry -> createPersonAssetStat(entry.getKey(), entry.getValue(), totalSum))
                    .sorted(Comparator.comparing(ZrrAssetStat::getRatio, Comparator.reverseOrder()))
                    .collect(Collectors.toList());
        }
    }

    private ZrrAssetStat createPersonAssetStat(String person, List<AssetsInfo> assets, BigDecimal totalSum) {
        long count = assets.size();
        BigDecimal totalValue = calculateTotalValue(assets);
        BigDecimal zjzje = calculateTotalZczjje(assets);
        BigDecimal ratio = calculateValueRatio(totalValue, totalSum);
        return new ZrrAssetStat(person, count, totalValue, ratio,assets.get(0).getZrrId(),zjzje);
    }

    private BigDecimal calculateTotalZczjje(List<AssetsInfo> assets) {
        BigDecimal reduce = assets.stream()
                .map(asset -> asset.getLjzjewy() == null ? BigDecimal.ZERO : asset.getLjzjewy())
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return reduce.divide(BigDecimal.valueOf(10000), BigDecimal.ROUND_HALF_UP);
    }

    private ZrrAssetStat createDepartAssetStat(String person, List<AssetsInfo> assets, BigDecimal totalSum) {
        long count = assets.size();
        BigDecimal totalValue = calculateTotalValue(assets);
        BigDecimal zjzje = calculateTotalZczjje(assets);
        BigDecimal ratio = calculateValueRatio(totalValue, totalSum);
        return new ZrrAssetStat(person, count, totalValue, ratio,assets.get(0).getZrbmId(),zjzje);
    }

    private JSONObject buildCategoryStatistics(List<AssetsInfo> assets,
                                               Function<AssetsInfo, String> classifier,
                                               BigDecimal totalSum,String type) {
        JSONObject stats = new JSONObject();
        Map<String, List<AssetsInfo>> grouped = assets.stream()
                .collect(Collectors.groupingBy(asset -> {
                    String value = classifier.apply(asset);
                    // 处理null和空字符串
                    if (value == null || value.trim().isEmpty()) {
                        return "未知分类"; // 或者您想要的其他默认值
                    }
                    return value;
                }));
        grouped.forEach((key, value) -> {
            JSONObject categoryStats = new JSONObject();
            categoryStats.put("count", value.size());
            categoryStats.put("countRatio", calculateRatio(value.size(), assets.size()));
            categoryStats.put("money", calculateTotalValue(value));
            categoryStats.put("moneyRatio", calculateValueRatio(calculateTotalValue(value), totalSum));
            if("未知分类".equals(key)) {
                stats.put("", categoryStats);
            }else {
                stats.put(key, categoryStats);
            }
        });

        return stats;
    }

    private JSONObject buildAssetStatusStatistics(List<AssetsInfo> assetsInfos, Map<String, List<AssetsInfo>> statusGroupedAssets, BigDecimal totalValue) {
        JSONObject statusStats = new JSONObject();
        // 使用预分组的数据，避免重复分组
        statusGroupedAssets.forEach((status, assets) -> {
            JSONObject assetStats = new JSONObject();
            assetStats.put("count", assets.size());
            // 使用预计算的总价值，避免重复计算
            JSONObject categoryStats = buildCategoryDistribution(assets, totalValue);
            assetStats.put("categoryDistribution", categoryStats);
            statusStats.put(status, assetStats);
        });

        return statusStats;
    }

    private JSONObject buildCategoryDistribution(List<AssetsInfo> assets, BigDecimal totalValue) {
        JSONObject distribution = new JSONObject();

        // 使用HashMap先收集数据，减少JSONObject的操作
        Map<String, CategoryStat> tempStats = new HashMap<>();


        // 一次遍历统计所有类别信息
        for (AssetsInfo asset : assets) {
            if (asset.getLb() == null) {
                continue;
            }
            CategoryStat stat = tempStats.computeIfAbsent(asset.getLb(), k -> new CategoryStat());
            stat.count++;
            BigDecimal assetValue = asset.getZcdqcbwy() != null ? asset.getZcdqcbwy() : BigDecimal.ZERO;
            stat.sum = stat.sum.add(assetValue);
        }


        // 并行计算占比并填充结果
        tempStats.entrySet().parallelStream().forEach(entry -> {
            String category = entry.getKey();
            CategoryStat stat = entry.getValue();

            JSONObject stats = new JSONObject();
            stats.put("money", stat.sum);

            // 计算占比
            if (totalValue != null && totalValue.compareTo(BigDecimal.ZERO) > 0) {
                stats.put("moneyRatio", stat.sum.divide(totalValue, SCALE, BigDecimal.ROUND_HALF_UP));
            } else {
                stats.put("moneyRatio", BigDecimal.ZERO);
            }

            synchronized(distribution) {
                distribution.put(category, stats);
            }
        });

        return distribution;
    }

    // 内部类用于临时统计
    private static class CategoryStat {
        int count = 0;
        BigDecimal sum = BigDecimal.ZERO;
    }

    private JSONObject buildDimensionStatistics(List<AssetsInfo> assetsInfos,
                                                Function<AssetsInfo, String> classifier,String type,BigDecimal totalValue) {
        JSONObject dimensionStats = new JSONObject();
        Map<String, List<AssetsInfo>> grouped = assetsInfos.stream()
                .collect(Collectors.groupingBy(asset -> {
                    String value = classifier.apply(asset);
                    // 处理null和空字符串
                    if (value == null || value.trim().isEmpty()) {
                        return "未知分类"; // 或者您想要的其他默认值
                    }
                    return value;
                }));

        grouped.forEach((key, assets) -> {
            JSONObject stats = buildDimensionDetailStats(assets, assetsInfos.size(), totalValue,type);
            if("未知分类".equals(key)) {
                dimensionStats.put("", stats);
            }else {
                dimensionStats.put(key, stats);
            }
        });

        return dimensionStats;
    }

    private JSONObject buildDimensionDetailStats(List<AssetsInfo> assets, int totalCount, BigDecimal totalSum,String type) {
        JSONObject stats = new JSONObject();
        stats.put("count", assets.size());
        stats.put("countRatio", calculateRatio(assets.size(), totalCount));
        // 根据type判断是否需要计算资产价值
        if("处置类型".equals(type)) {
            BigDecimal money = calculateTotalValueYscgje(assets);
            stats.put("money", money);
            stats.put("moneyRatio", calculateValueRatio(money, totalSum));
        }else {
            BigDecimal money = calculateTotalValue(assets);
            stats.put("money", money);
            stats.put("moneyRatio", calculateValueRatio(money, totalSum));
        }
        stats.put("assetsInfoDetailsList", buildAssetsDetails(assets));

        return stats;
    }

    private List<AssetsInfoDetails> buildAssetsDetails(List<AssetsInfo> assets) {
        return assets.stream()
                .map(this::convertToAssetsInfoDetails)
                .collect(Collectors.toList());
    }

    private AssetsInfoDetails convertToAssetsInfoDetails(AssetsInfo assetsInfo) {
        AssetsInfoDetails details = new AssetsInfoDetails();
        details.setZcmc(assetsInfo.getZcmc());
        details.setSblb(assetsInfo.getLb());
        details.setZcrkbh(assetsInfo.getZcrkbh());
        details.setZcjzje(assetsInfo.getZcdqcbwy());
        details.setWz(assetsInfo.getSydd());
        details.setZczt(assetsInfo.getZczt());
        return details;
    }

    private JSONObject buildDepartmentStatistics(List<AssetsInfo> assetsInfos, Map<String, List<AssetsInfo>> departmentGroupedAssets, BigDecimal totalValue,Map<String, List<ZczjStatInfo>> departGroupedZczjStatInfos,Map<String, List<AssetsInfo>> departmentGroupedAssetsYzc) {
        JSONObject departmentStats = new JSONObject();
          // 部门资产统计排名
        List<DepartMentAssetStat> departmentRanking = buildDepartmentRanking(departmentGroupedAssets, totalValue);
        departmentStats.put("bmzctj", departmentRanking);

        // 部门详细信息
        JSONObject departmentDetails = buildAllDepartmentDetails(departmentGroupedAssets,departGroupedZczjStatInfos,departmentGroupedAssetsYzc);
        departmentStats.put("list", departmentDetails);

        return departmentStats;
    }

    private List<DepartMentAssetStat> buildDepartmentRanking(Map<String, List<AssetsInfo>> departmentGroupedAssets,
                                                             BigDecimal totalSum) {
        // 使用预分配大小的列表提高性能
        List<DepartMentAssetStat> ranking = new ArrayList<>(departmentGroupedAssets.size());

        // 并行处理部门数据，提高大数据量下的性能
        departmentGroupedAssets.entrySet().parallelStream()
                .map(entry -> createDepartmentAssetStat(entry.getKey(), entry.getValue(), totalSum))
                .forEach(ranking::add);

        // 排序
        ranking.sort(Comparator.comparing(DepartMentAssetStat::getRatio, Comparator.reverseOrder()));

        return ranking;
    }

    private DepartMentAssetStat createDepartmentAssetStat(String department, List<AssetsInfo> assets, BigDecimal totalSum) {
        int count = assets.size();
        String departId ="";
        if (count > 0) {
             departId = assets.get(0).getDepartId();
        }
        BigDecimal totalValue = calculateTotalValue(assets);
        BigDecimal ratio = calculateValueRatio(totalValue, totalSum);
        return new DepartMentAssetStat(departId,department, count, totalValue, ratio);
    }

    private JSONObject buildAllDepartmentDetails(Map<String, List<AssetsInfo>> groupedByDepartment,Map<String, List<ZczjStatInfo>> departGroupedZczjStatInfos,Map<String, List<AssetsInfo>> departmentGroupedAssetsYzc) {
        JSONObject allDetails = new JSONObject();

        groupedByDepartment.forEach((department, assets) -> {
            JSONObject detail = buildSingleDepartmentDetail(assets,departGroupedZczjStatInfos.get(department),departmentGroupedAssetsYzc.get(department));
            allDetails.put(department, detail);
        });

        return allDetails;
    }

    private JSONObject buildSingleDepartmentDetail(List<AssetsInfo> departmentAssets,List<ZczjStatInfo> zczjStatInfos,List<AssetsInfo> yczList) {
        JSONObject detail = new JSONObject();
        BigDecimal departTotalSum = calculateTotalValueJz(departmentAssets);
        BigDecimal departTotalSumYz = calculateTotalValue(departmentAssets);

        detail.put("count", departmentAssets.size());
        detail.put("totalMoneyJz", departTotalSum);
        detail.put("totalMoneyYz", departTotalSumYz);
        detail.put("zrrzcjzpm", buildPersonAssetRanking(departmentAssets, departTotalSumYz,"depart"));
        detail.put("zcdl", buildCategoryStatistics(departmentAssets, AssetsInfo::getZcdl, departTotalSumYz,"资产大类"));
        detail.put("zcyt", buildCategoryStatistics(departmentAssets, AssetsInfo::getZcyt, departTotalSumYz,"资产用途"));
        detail.put("sbzt", buildCategoryStatistics(departmentAssets, AssetsInfo::getSbzt, departTotalSumYz,"设备状态"));
        detail.put("cgfs", buildCategoryStatistics(departmentAssets, AssetsInfo::getCgfs, departTotalSumYz,"采购方式"));
        detail.put("currentPeriodDetailReport", RkStatUtils.getCurrentPeriodDetailReport(departmentAssets));
        detail.put("currentPeriodFinancialReport", ZjStatUtil.getCurrentPeriodFinancialReport(zczjStatInfos));
        // 资产价值数量统计
        detail.put("zcjzsltj", AssetsMoneyNumStatUtils.getCurrentPeriodDetailReport(departmentAssets));
        // 资产折旧统计
        detail.put("zcbftj", AssetsBfStatUtils.getCurrentPeriodDetailReport(yczList));
        return detail;
    }

    private List<DepartmentAssetsDetailsInfo> buildDepartmentAssetsDetails(Map<String, List<AssetsInfo>> groupedByDepartment) {
        List<DepartmentAssetsDetailsInfo> result = new ArrayList<>();
        groupedByDepartment.forEach((department, assets) -> {
            List<AssetsInfo> sortedAssets = sortAssetsByValue(assets);
            result.addAll(convertToDepartmentAssetsDetails(department, sortedAssets));
        });

        return result;
    }

    private List<YqAssetsDetailsInfo> buildParkAssetsDetails(Map<String, List<AssetsInfo>> parkGroupedAssets) {
        List<YqAssetsDetailsInfo> result = new ArrayList<>();
        parkGroupedAssets.forEach((park, assets) -> {
            List<AssetsInfo> sortedAssets = sortAssetsByValue(assets);
            result.addAll(convertToParkAssetsDetails(park, sortedAssets));
        });

        return result;
    }

    private List<AssetsInfo> sortAssetsByValue(List<AssetsInfo> assets) {
        return assets.stream()
                .sorted(Comparator.comparing(AssetsInfo::getZcdqcbwy,
                        Comparator.nullsLast(Comparator.reverseOrder())))
                .collect(Collectors.toList());
    }

    private List<DepartmentAssetsDetailsInfo> convertToDepartmentAssetsDetails(String department,
                                                                               List<AssetsInfo> assets) {
        return assets.stream()
                .map(asset -> createDepartmentAssetsDetail(department, asset))
                .collect(Collectors.toList());
    }

    private DepartmentAssetsDetailsInfo createDepartmentAssetsDetail(String department, AssetsInfo asset) {
        DepartmentAssetsDetailsInfo detail = new DepartmentAssetsDetailsInfo();
        detail.setBm(department);
        detail.setZcrkbh(asset.getZcrkbh());
        detail.setZcjz(asset.getZcdqcbwy().divide(BigDecimal.valueOf(10000), BigDecimal.ROUND_HALF_UP));
        detail.setZcdl(asset.getZcdl());
        detail.setZcytmx(asset.getZcytmx());
        detail.setZcmc(asset.getZcmc());
        detail.setDetailInfo(createDetailInfo(asset));
        return detail;
    }

    private List<YqAssetsDetailsInfo> convertToParkAssetsDetails(String park, List<AssetsInfo> assets) {
        return assets.stream()
                .map(asset -> createParkAssetsDetail(park, asset))
                .collect(Collectors.toList());
    }

    private YqAssetsDetailsInfo createParkAssetsDetail(String park, AssetsInfo asset) {
        YqAssetsDetailsInfo detail = new YqAssetsDetailsInfo();
        detail.setYq(park);
        detail.setZcrkbh(asset.getZcrkbh());
        detail.setZcjz(asset.getZcdqcbwy().divide(BigDecimal.valueOf(10000), BigDecimal.ROUND_HALF_UP));
        detail.setZcdl(asset.getZcdl());
        detail.setZcytmx(asset.getZcytmx());
        detail.setZcmc(asset.getZcmc());
        detail.setDetailInfo(createDetailInfo(asset));
        return detail;
    }

    private DetailInfo createDetailInfo(AssetsInfo asset) {
        DetailInfo detail = new DetailInfo();
        detail.setZcrkbh(asset.getZcrkbh());
        detail.setZcmc(asset.getZcmc());
        detail.setSyzt(asset.getZcsyzt());
        detail.setSbxh(asset.getXh());
        detail.setPp(asset.getPp());
        detail.setGgxh(asset.getGgcs());
        detail.setGys(asset.getGyswb());
        detail.setSydd(asset.getSydd());
        return detail;
    }

    // 工具方法
    private BigDecimal calculateTotalValue(List<AssetsInfo> assets) {
        BigDecimal reduce = assets.stream()
                .map(asset -> asset.getZcdqcbwy() == null ? BigDecimal.ZERO : asset.getZcdqcbwy())
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return reduce.divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
    }
    private BigDecimal calculateTotalValueYscgje(List<AssetsInfo> assets) {
        BigDecimal reduce = assets.stream()
                .map(asset -> asset.getYscgjewy() == null ? BigDecimal.ZERO : asset.getYscgjewy())
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return reduce.divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
    }
    private BigDecimal calculateTotalValueJz(List<AssetsInfo> assets) {
        BigDecimal reduce = assets.stream()
                .map(asset -> asset.getZcjzwy() == null ? BigDecimal.ZERO : asset.getZcjzwy())
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return reduce.divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);
    }

    private BigDecimal calculateRatio(int part, int total) {
        return total > 0 ?
                new BigDecimal(part).divide(new BigDecimal(total), SCALE, BigDecimal.ROUND_HALF_UP) :
                BigDecimal.ZERO;
    }

    private BigDecimal calculateValueRatio(BigDecimal part, BigDecimal total) {
        return Optional.ofNullable(total)
                .filter(t -> t.compareTo(BigDecimal.ZERO) > 0)
                .flatMap(t -> Optional.ofNullable(part).map(p -> p.divide(t, SCALE, BigDecimal.ROUND_HALF_UP)))
                .orElse(BigDecimal.ZERO);
    }

    // 查询返回的列表数据组装为AssetsInfo对象
    private AssetsInfo extractAssetsInfo(RecordSet recordSet) {
        AssetsInfo assetsInfo = new AssetsInfo();
        // 设置基础字段
        setBasicFields(assetsInfo, recordSet);

        // 设置转换字段
        setConvertedFields(assetsInfo, recordSet);

        // 设置数值字段
        setNumericFields(assetsInfo, recordSet);

        return assetsInfo;
    }
    // 批量加载部门信息
    private void loadDepartmentInfoBatch(List<AssetsInfo> assetsInfos) {
        Set<String> deptIds = new HashSet<>();
        for (AssetsInfo asset : assetsInfos) {
            String departId = asset.getDepartId();
            if (departId != null && !departId.isEmpty()) {
                deptIds.add(departId);
            }
        }

        if (!deptIds.isEmpty()) {
            Map<String, String> deptMap = new HashMap<>();
            String deptSql = "select id, departmentname from hrmdepartment where id in (" + String.join(",", deptIds) + ")";
            RecordSet recordSet = new RecordSet();
            recordSet.executeQuery(deptSql);
            while (recordSet.next()) {
                deptMap.put(recordSet.getString("id"), recordSet.getString("departmentname"));
            }

            // 更新部门名称
            for (AssetsInfo asset : assetsInfos) {
                String departId = asset.getDepartId();
                if (departId != null && deptMap.containsKey(departId)) {
                    asset.setZrbm(deptMap.get(departId));
                    asset.setZrbmId(departId);
                }
            }
        }
    }
    // 查询返回的列表数据组装为ZczjStatInfo对象
    private ZczjStatInfo extractZczjStatInfo(RecordSet recordSet) {
        ZczjStatInfo zczjStatInfo = new ZczjStatInfo();
        setField(zczjStatInfo::setGxrq, recordSet.getString("gxrq"));
        setField(zczjStatInfo::setZcbq, recordSet.getString("zcbq"));
        setField(zczjStatInfo::setZcjz, parseBigDecimal(recordSet.getString("zcjz")));
        // 责任部门
        setField(zczjStatInfo::setZrbm, recordSet.getString("zrbm"));
        setField(zczjStatInfo::setCfyq, recordSet.getString("cfyq"));
        return  zczjStatInfo;
    }

    private void setBasicFields(AssetsInfo assetsInfo, RecordSet recordSet) {
        setField(assetsInfo::setId, recordSet.getString("id"));
        setField(assetsInfo::setZctp, recordSet.getString("zctp"));
        setField(assetsInfo::setGyswb, recordSet.getString("gyswb"));
        setField(assetsInfo::setZcrkbh, recordSet.getString("zcrkbh"));
        setField(assetsInfo::setZcmc, recordSet.getString("zcmc"));
        setField(assetsInfo::setXh, recordSet.getString("xh"));

        // 责任人处理 - 直接设置ID，后续在批量加载时更新为名称
        String zrr = recordSet.getString("zrr");
        assetsInfo.setZrr(Objects.equals(zrr, "") ? null : zrr);

        setField(assetsInfo::setPp, recordSet.getString("pp"));
        setField(assetsInfo::setGgcs, recordSet.getString("ggcs"));
        setField(assetsInfo::setZcdl, recordSet.getString("zcdl"));
        setField(assetsInfo::setGys, recordSet.getString("gys"));
        setField(assetsInfo::setZcytmx, recordSet.getString("zcytmx"));
        setField(assetsInfo::setCfyq, recordSet.getString("cfyq"));
        setField(assetsInfo::setSydd, recordSet.getString("sydd"));
        setField(assetsInfo::setZjnxn, recordSet.getString("zjnxn"));
        setField(assetsInfo::setDepartId, recordSet.getString("zrbm"));
        setField(assetsInfo::setRkrq,recordSet.getString("rkrq"));
        setField(assetsInfo::setRzsj,recordSet.getString("rzsj"));
        setField(assetsInfo::setSbzt,recordSet.getString("sbzt"));
        setField(assetsInfo::setCzlx, recordSet.getString("czlx"));
        setField(assetsInfo::setAzlx, recordSet.getString("azlx"));
        setField(assetsInfo::setQyrq, recordSet.getString("qyrq"));
        setField(assetsInfo::setCzrq,recordSet.getString("czrq"));
        setField(assetsInfo::setLb, recordSet.getString("lb"));
    }

    // 通用字段设置方法，减少重复代码
    private <T> void setField(Consumer<T> setter, T value) {
        if (value != null && !value.equals("")) {
            setter.accept(value);
        }
    }

    private void setConvertedFields(AssetsInfo assetsInfo, RecordSet recordSet) {
        // 提醒周期
//        assetsInfo.setTxzq(convertTxzq(recordSet.getString("txzq")==null?"":recordSet.getString("txzq")));
        // 资产状态
        assetsInfo.setZczt(convertZczt(recordSet.getString("zczt")==null?"":recordSet.getString("zczt")));
        // 资产类别
//        assetsInfo.setLb(convertLb(recordSet.getString("lb")==null?"":recordSet.getString("lb")));
        // 安装类型
//        assetsInfo.setAzlx(convertAzlx(recordSet.getString("azlx")==null?"":recordSet.getString("azlx")));
        // 设备状态
//        assetsInfo.setSbzt(convertSbzt(recordSet.getString("sbzt")==null?"":recordSet.getString("sbzt")));
        // 取得方式
//        assetsInfo.setQdfs(convertQdfs(recordSet.getString("qdfs")==null?"":recordSet.getString("qdfs")));
        // 采购来源
//        assetsInfo.setCgly(convertCgly(recordSet.getString("cgly")==null?"":recordSet.getString("cgly")));
        // 采购方式
        assetsInfo.setCgfs(convertCgfs(recordSet.getString("cgfs")==null?"":recordSet.getString("cgfs")));
        // 资产用途
        assetsInfo.setZcyt(convertZcyt(recordSet.getString("zcyt")==null?"":recordSet.getString("zcyt")));
        // 是否配件
//        assetsInfo.setSfpj(convertSfpj(recordSet.getString("sfpj")==null?"":recordSet.getString("sfpj")));
        // 资产使用状态
        assetsInfo.setZcsyzt(convertZcsyzt(recordSet.getString("zcsyzt")==null?"":recordSet.getString("zcsyzt")));
        // 资产处置类型
//        assetsInfo.setCzlx(convertCzlx(recordSet.getString("czlx")==null?"":recordSet.getString("czlx")));
        // 资产账簿
//        assetsInfo.setZczb(convertZczb(recordSet.getString("zczb")==null?"":recordSet.getString("zczb")));
        // 是否入账
//        assetsInfo.setSfrz(convertSfrz(recordSet.getString("sfrz")==null?"":recordSet.getString("sfrz")));
    }

    private void setNumericFields(AssetsInfo assetsInfo, RecordSet recordSet) {
        setField(assetsInfo::setYscgjewy, parseBigDecimal(recordSet.getString("yscgjewy")));
        setField(assetsInfo::setZcdqcbwy, parseBigDecimal(recordSet.getString("zcdqcbwy")));
        setField(assetsInfo::setLjzjewy, parseBigDecimal(recordSet.getString("ljzjewy")));
        setField(assetsInfo::setZcjzwy, parseBigDecimal(recordSet.getString("zcjzwy")));
    }

    private BigDecimal parseBigDecimal(String value) {
        try {
            return value == null || value.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(value);
        } catch (NumberFormatException e) {
            // 异常情况下返回0，避免转换失败
            return BigDecimal.ZERO;
        }
    }

    // 使用静态Map替换switch-case，提高性能和可维护性
//    private static final Map<String, String> TXZQ_MAP = new HashMap<String, String>() {{
//        put("0", "提前7天");
//        put("1", "提前10天");
//        put("2", "提前15天");
//    }};

    private static final Map<String, String> ZCZT_MAP = new HashMap<String, String>() {{
        put("0", "固定资产");
        put("1", "项目资产");
    }};

//    private static final Map<String, String> LB_MAP = new HashMap<String, String>() {{
//        put("0", "重要设备");
//        put("1", "特种设备");
//        put("2", "关键设备");
//        put("3", "辅助类");
//        put("4", "计量类");
//        put("5", "加工类");
//        put("6", "转运车辆");
//        put("7", "军工");
//    }};

//    private static final Map<String, String> AZLX_MAP = new HashMap<String, String>() {{
//        put("0", "便携式");
//        put("1", "固定式");
//        put("2", "固定可移动式");
//    }};

//    private static final Map<String, String> SBZT_MAP = new HashMap<String, String>() {{
//        put("完好", "完好");
//        put("封存", "封存");
//        put("退库", "退库");
//    }};

//    private static final Map<String, String> QDFS_MAP = new HashMap<String, String>() {{
//        put("0", "采购");
//        put("1", "基建转入");
//        put("2", "研制转入");
//    }};

//    private static final Map<String, String> CGLY_MAP = new HashMap<String, String>() {{
//        put("0", "国产");
//        put("1", "直接进口");
//        put("2", "间接进口");
//    }};

    private static final Map<String, String> CGFS_MAP = new HashMap<String, String>() {{
        put("0", "公开招标");
        put("1", "邀请招标");
        put("2", "单一来源");
        put("3", "竞争性谈判");
        put("4", "竞争性磋商");
        put("5", "询价");
        put("6", "框架协议");
        put("7", "合作创新");
        put("8", "其他");
        put("9","院网网上采购");
    }};

    private static final Map<String, String> ZCYT_MAP = new HashMap<String, String>() {{
        put("0", "科研用");
        put("1", "非科研用");
    }};

//    private static final Map<String, String> SFPJ_MAP = new HashMap<String, String>() {{
//        put("0", "是");
//        put("1", "否");
//    }};

    private static final Map<String, String> ZCSYZT_MAP = new HashMap<String, String>() {{
        put("0", "使用中");
        put("1", "已处置");
        put("2", "已处置申报");
    }};

//    private static final Map<String, String> CZLX_MAP = new HashMap<String, String>() {{
//        put("0", "报废报损");
//        put("1", "无偿调拨");
//        put("2", "其它");
//    }};
//
//    private static final Map<String, String> ZCZB_MAP = new HashMap<String, String>() {{
//        put("0", "固定资产");
//        put("1", "非固定资产");
//    }};

//    private static final Map<String, String> SFRZ_MAP = new HashMap<String, String>() {{
//        put("0", "是");
//        put("1", "否");
//    }};

    // 转换方法
//    private String convertTxzq(String value) {
//        return value != null ? TXZQ_MAP.getOrDefault(value, "") : "";
//    }

    private String convertZczt(String value) {
        return value != null ? ZCZT_MAP.getOrDefault(value, "") : "";
    }

//    private String convertLb(String value) {
//        return value != null ? LB_MAP.getOrDefault(value, "") : "";
//    }

//    private String convertAzlx(String value) {
//        return value != null ? AZLX_MAP.getOrDefault(value, "") : "";
//    }

//    private String convertSbzt(String value) {
//        return value != null ? SBZT_MAP.getOrDefault(value, "") : "";
//    }

//    private String convertQdfs(String value) {
//        return value != null ? QDFS_MAP.getOrDefault(value, "") : "";
//    }

//    private String convertCgly(String value) {
//        return value != null ? CGLY_MAP.getOrDefault(value, "") : "";
//    }
//
    private String convertCgfs(String value) {
        return value != null ? CGFS_MAP.getOrDefault(value, "") : "";
    }

    private String convertZcyt(String value) {
        return value != null ? ZCYT_MAP.getOrDefault(value, "") : "";
    }

//    private String convertSfpj(String value) {
//        return value != null ? SFPJ_MAP.getOrDefault(value, "") : "";
//    }

    private String convertZcsyzt(String value) {
        return value != null ? ZCSYZT_MAP.getOrDefault(value, "") : "";
    }

//    private String convertCzlx(String value) {
//        return value != null ? CZLX_MAP.getOrDefault(value, "") : "";
//    }
//
//    private String convertZczb(String value) {
//        return value != null ? ZCZB_MAP.getOrDefault(value, "") : "";
//    }

//    private String convertSfrz(String value) {
//        return value != null ? SFRZ_MAP.getOrDefault(value, "") : "";
//    }
}